/**
	This file is part of Fighting Field.

    Fighting Field is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Fighting Field is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Fighting Field.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef FF_INPUTMANAGER_H
#define FF_INPUTMANAGER_H

#include "Prerequisites.h"

namespace FF
{
	class InputListener;
}

namespace FF
{
	struct InputLayer
	{
		enum Val { Gui = 0, Scene, Nb };
	};

	class InputManager
		: public OIS::KeyListener
		, public OIS::MouseListener
		, public Ogre::WindowEventListener
	{
	public:
		InputManager(Ogre::RenderWindow* window);
		~InputManager();

		void Update(const Ogre::Real& dt);

		void RegisterListener(InputLayer::Val layer, InputListener* listener);
		void UnregisterListener(InputLayer::Val layer, InputListener* listener);
		InputListener* GetRegisteredListener(InputLayer::Val layer) { return mListeners[layer]; }
		InputListener* GetActiveListener() { return mActiveListener; }

		bool IsPressedKey(OIS::KeyCode code) const { return mPressedKeys[code]; }
		bool IsPressedButton(OIS::MouseButtonID id) const { return (mPressedButtons & (1 << (unsigned int)id)) != 0; }

		OIS::InputManager* GetInternalInputManager() const { return mInputManager; }
		OIS::Keyboard* GetKeyboard() const { return mKeyboard; }
		OIS::Mouse* GetMouse() const { return mMouse; }

	protected:
		// OIS callbacks
		bool keyPressed(const OIS::KeyEvent& evt);
		bool keyReleased(const OIS::KeyEvent& evt);

		bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
		bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
		bool mouseMoved(const OIS::MouseEvent& evt);

		void windowResized(Ogre::RenderWindow* window);

	protected:
		OIS::InputManager* mInputManager;
		OIS::Keyboard* mKeyboard;
		OIS::Mouse* mMouse;

		InputListener* mListeners[InputLayer::Nb];
		InputListener* mActiveListener;

		unsigned int mPressedButtons;
		bool mPressedKeys[100];
		unsigned int mNbPressedKeys;
	};
}

#endif